#include <REGX52.H>

//距离小于10cm,D5亮，D6灭，反之相反
int angle;
int cot; 
int mark_vibrate;
int angle_bak;

sbit D5      = P3^7;//设备变量led1指向P3组IO口的第7口
sbit D6      = P3^6;//设备变量led2指向P3组IO口的第6口
sbit SW      = P2^1;//开关接P2.1口
sbit Trig    = P1^5;//超声波模块trig口接P1组IO口第5口
sbit Echo    = P1^6;//超声波模块trig口接P1组IO口第6口
sbit sg90    = P1^1;//舵机接到P1.0口
sbit beep    = P2^0;//蜂鸣器接到P2.0口
sbit vibrate = P3^2;//振动器接P3.2口


void Delayms(int ms)		//@11.0592MHz
{
	unsigned char i, j;

	while(ms){
		i = 2;
		j = 199;
		do
		{
		while (--j);
		} while (--i);
		ms --;
	}
}

void Delay10us()		//@11.0592MHz
{
	unsigned char i;

	i = 2;
	while (--i);
}


//超声波T1定时器初始化
void Timer1Init(){

	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x10;		//设置定时器模式
	TL1 = 0;		//设置定时初值
	TH1 = 0;	//设置定时初值
	
}

//舵机T0定时器初始化
void InitTime0()		//0.5毫秒@11.0592MHz
{
	TMOD &= 0xF0;    // 清除TMOD的低4位
    TMOD |= 0x01;    // 设置定时器0为模式1 (16位定时器)
	TL0  = 0x33;		//设置定时初值
	TH0  = 0xFE;		//设置定时初值	
	TR0  = 1;		//定时器0开始计时
	TF0  = 0;	//清除TF0标志
	//启动中断
	EA  = 1;
	ET0 = 1;
	
}

void T0Handler() interrupt 1{
	
	cot++;
	TL0 = 0x33;
	TH0 = 0xFE;	
	

	if(cot < angle){
		sg90 = 1;
	}else{
		sg90 = 0;
	}
	
	if(cot == 40){
	
		cot  = 0;
		sg90 = 1;
	}
}

void EX0_Init(){

	EX0 = 1;
	IT0 = 0;
}

double distance(){

	double time = 0;
	
	TH1 = 0;
	TL1 = 0;
	
	//给trig高电平持续10us；
	Trig = 0;
	Trig = 1;       
	Delay10us();
	Trig = 0;
	
	//检测发送接收信号时间
	while(Echo == 0);
	TR1 = 1;
	while(Echo == 1);
	TR1 = 0;
	
	// 计算时间高位左移8位即2^8=256
	time = (TH1 * 256 + TL1) * 1.085; //记一位耗时1.085us； 
	
	//计算距离声速（340m/s）* 时间 除以2（往返走过两次距离）
	return 0.017 * time;
}




void opensg90state(){

		angle = 3 ;
	
		if(angle_bak != angle){
		cot = 0; 
		beep = 0;
		Delayms(150);
		beep = 1;
		Delayms(2000);	
	}
	angle_bak = angle;
}

void openled(){

	D5 = 1;
	D6 = 0;
}

void closeled(){

	D5 = 0;
	D6 = 1;  
}

void initSG90_0()
{

	angle = 1; //初始角度是0度，0.5ms,溢出1就是0.5，高电平
	cot = 0;
	vibrate = 1;//一开始从高电平开始
}

void closesg90(){
		
	angle = 1;
	angle_bak = angle;
	cot = 0;
	Delayms(150);
}

int main(){
	
	//初始化角度，距离，和蜂鸣器状态
	double dis   = 0;
	beep         = 1;
	mark_vibrate = 0;
	//初始化定时器
	Timer1Init();
	InitTime0();
	EX0_Init();
	initSG90_0();
	
	while(1){
		dis = distance();
		if(dis < 10 || mark_vibrate == 1 || SW == 0){
			
			openled();
			opensg90state();
			mark_vibrate = 0;
			
			}
			else{

			closesg90();
			closeled();
		}
	}	
}


void mark_vibratestate() interrupt 0
{
	mark_vibrate = 1;
}

